/*
为什么要写这个驱动：
网上已经有一些ads1299的驱动了，但是如openbci那种，不够简单清晰，一层层的封装，还有一些为了他们自己的板子适配的功能，阅读和维护都很麻烦。
github上也有简单的，但我需要同时驱动几块ads1299,做一个多通道的，也不好用。所以还是自己写一个,满足自己的需求，并且尽量简洁，注重运行效率。
参考了：
https://github.com/UO-Bionics-MindMetrics/ADS1299-Arduino-Driver/tree/main
https://github.com/Borchevkin/drv_ads1299/tree/master
https://github.com/starcat-io/hackeeg-driver-arduino/tree/main/hackeeg_driver
openbci
 
关于ads1299：

和之前我用过的普通的adc最大的不同大概是这个芯片有一个上电流程（说明书62页），如果哪里不对，要关注下这个地方是不是有问题。

我一开始为了验证spi通讯，尝试去读device_id，用示波器看spi时序波形，怎么都是对的，就是MISO信号出不来，
后来发现上电后，他会自动进入RDATAC的模式，如果要读deviceID，需要先发一个SDATAC的命令，不然读不出。
这个是看了
https://github.com/UO-Bionics-MindMetrics/ADS1299-Arduino-Driver/blob/main/src/ADS1299.cpp 58行 void ADS1299::RREG(byte _address) 这个函数
的代码发现的

如果不想用RESET，发送RESET命令（命令表，说明书40页）也是一样的效果（说明书35页）。

在我的板子上，我将RESET和PWDN两个引脚直接接到了3.3v。（以后可以考虑将PWDN连到一个GPIO脚上，不用的时候可以关掉降低功耗）

我这里多个ads1299公用一套spi线，各有自己的CS线。如果只有一片ads1299，可以不设置CS线（默认是-1），这样可以在spi配置那里配置为硬件CS。

目前我只写出了我用得到的基本功能，其他功能用到了再写。

我这里主控用的esp32，其他的芯片应该也可以，但我没有实验过。
*/

#ifndef __ADS1299_DRV_X_H__
#define __ADS1299_DRV_X_H__

#include "ads1299x.h"


//////////////////////////////////////////////////////////////////////////////////////
/*switch this two if switch 4 chips and 1 chips*/
// #define USE_4_CHIPS 


#ifdef USE_4_CHIPS
#define CHIP_NUM 4
#else
#define CHIP_NUM 1
#endif

/*note this for use raw data or use json data*/ 
#ifdef USE_4_CHIPS
#define pkg_use_raw_data 1 // defined this means use raw data
#else
#define pkg_use_int_data 1 // defined this means use int but not json
#endif
// #define pkg_use_json 1 // defined this means use int in json format

// #define pkg_use_raw_data 1 // defined this means use raw data



#define ADS_DRDY_PIN GPIO_NUM_32 // Pin 12

#define SPI_CS_0 GPIO_NUM_27 // Pin 16, according to esp32-pico-d4_datasheet
// #define SPI_CS_0 GPIO_NUM_15 // Pin 21

/* gpio pins and spi pins ,
comment this CS pins if not use, in the code we will use like "ifdef SPI_CS_1"
*/
#ifdef USE_4_CHIPS

// #define SPI_CS_2 GPIO_NUM_27 // Pin 21
// #define SPI_CS_1 GPIO_NUM_26 // Pin 15

// #define SPI_CS_1 GPIO_NUM_15 // Pin 21
// #define SPI_CS_2 GPIO_NUM_26 // Pin 15
// #define SPI_CS_3 GPIO_NUM_33 // Pin 13 
// the order of spi_cs lines matters, because they determine the channel order in the data  
#define SPI_CS_1 GPIO_NUM_26 // Pin 15
#define SPI_CS_2 GPIO_NUM_33 // Pin 13 
#define SPI_CS_3 GPIO_NUM_15 // Pin 21 

#define PIN_NUM_MISO 12 // pin 18
#define PIN_NUM_MOSI 13 // pin 20
#define PIN_NUM_CLK 14  // pin 17
#define ADS_DRV_START_PIN GPIO_NUM_25 // Pin 14
#define GPIO_OUTPUT_PIN_SEL ((1ULL << SPI_CS_0) | (1ULL << SPI_CS_1) | (1ULL << SPI_CS_2) | (1ULL << SPI_CS_3) | (1ULL << ADS_DRV_START_PIN))

#else
#define PIN_NUM_MISO 25 // pin 14
#define PIN_NUM_MOSI 14 // pin 17
#define PIN_NUM_CLK 26  // pin 15
#define ADS_DRV_START_PIN GPIO_NUM_12 // Pin 18
#define GPIO_OUTPUT_PIN_SEL ((1ULL << SPI_CS_0) | (1ULL << ADS_DRV_START_PIN))

#endif


#define CHANNEL_NUM 8 //how many channels you want to use in your ads1299 chip

//////////////////////////////////////////////////////////////////////////////////////

#define RX_BUFF_LEN_INT_ARRAY CHIP_NUM*CHANNEL_NUM*4 //sizeof int is 4 bytes, when use ads1299_drv_get_data(), this can be used on the len of the rx buff
#define RX_BUFF_LEN_RAW_24b CHIP_NUM*CHANNEL_NUM*3 // raw data is 3 bytes, when use ads1299_drv_get_data_int_array(), this can be used on the len of the rx buff

////////////////////////////////////////////////////////////////////////////////////// for transfer data 10 samples in a packet

#define sample_num_in_pkg 10


#ifdef pkg_use_raw_data
// 9(channels) means Status Register+ 8-Channel Data , totally 27 bytes (216 Bits)
// #define ads_data_sample_len 9*3*CHIP_NUM //9(channels)*3(bytes, 24bit adc)*n(chips); 
// #define ads_pkg_data_len ads_data_sample_len*sample_num_in_pkg //9(channels)*3(bytes)*3(chips)*10(samples)
#define ads_raw_data_len 9*3*CHIP_NUM //9(channels)*3(bytes, 24bit adc)*3(chips); 
#define ads_pkg_raw_data_len ads_raw_data_len*sample_num_in_pkg //9(channels)*3(bytes)*3(chips)*10(samples)
#endif

#ifdef pkg_use_int_data
#define ads_int_data_len 8*CHIP_NUM //8(channels)*1(int actually 4 bytes)*3(chips)
#define ads_int_data_len_in_byte 8*sizeof(int)*CHIP_NUM //8(channels)*4(1 int actually 4 bytes)*3(chips)
#define ads_pkg_int_data_len_in_byte ads_int_data_len_in_byte*sample_num_in_pkg //use int 8(channels)*3(chips)*10(samples) ignore status register
// #define ads_pkg_int_data_len ads_data_sample_len_in_int*sample_num_in_pkg //use int 8(channels)*3(chips)*10(samples) ignore status register
// #define ads_pkg_int_data_len_in_byte ads_pkg_int_data_len*sizeof(int)
#endif


#ifdef pkg_use_json
int json_pkg_num = 0;
#endif


/*use as the counter with data_ads_pkg_t to locate the adress, which the data should be put into */
typedef struct index_counter_in_data_packet_t
{
// #ifdef pkg_use_int_data  
// unsigned short ads_sample_int_offset_in_data_packet;
// #endif
unsigned short ads_sample_counter;

} ads_dp_ic_t;


typedef struct data_ads_pkg_t
{
#ifdef pkg_use_int_data   
	const short head;
    unsigned short pkg_num;
    char data[ads_pkg_int_data_len_in_byte];
    const short tail;
#endif

#ifdef pkg_use_raw_data 
    // uint8_t data[ads_pkg_data_len]; 
    // // uint8_t data[810]; // 9(channels)*3(bytes)*3(chips)*10(samples) = 810
    // uint16_t pkg_num;
	const short head;
    unsigned short pkg_num;
    char data[ads_pkg_raw_data_len];
    const short tail;
#endif

#ifdef pkg_use_json    
    int data[ads_pkg_data_int_len];
#endif

} data_ads_pkg_t;

#define FRAME_HEAD 0xA5A5
// #define FRAME_TAIL 0x90EB
#define FRAME_TAIL 0x5A5A

/* check it, 
with different setup of CHIP_NUM and int_or_raw, it should be:
CHIP_NU\pkg_use_int_data    int_data    raw_data
1                           326         276
4                           1286        1086
*/
#define ADS_DATA_PACKET_LEN sizeof(data_ads_pkg_t) 

#define DATA_ADS_INIT(_name) data_ads_pkg_t _name = {.head = FRAME_HEAD, .tail = FRAME_TAIL };

/// @brief /////////////////////////////////////////////////////////////////////
typedef void (* ads1299_drv_handler_t) (uint8_t * p_data, uint16_t len);

typedef struct 
{	
	ads1299_drv_handler_t callback_handler;		// callback function
}ads1299_drv_t;

typedef enum {
    REC_ON,
    REC_OFF
} ads1299_rec_status_t;

ads1299_rec_status_t get_rec_status(void);

void ads1299_dev_init(ads1299_drv_t m_drv);

void ads1299_drv_check_id(void);

void ads1299_dev_start(void);

void ads1299_drv_get_data(char * rx);

// void ads1299_drv_get_data_int_array(int * rx_int);
void ads1299_drv_get_data_int_array(int * rx_int,uint8_t *rx_status);

void ads1299_dev_start_recording(void);

void ads1299_dev_stop_recording(void);

void ads1299_drv_get_leadoff_status_rx(uint8_t * rx);
void ads1299_drv_get_leadoff_status(void);

#endif